package com.xyy.config;

import com.xyy.util.JwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;

/**
 * JWT拦截器
 */
@Slf4j
@Component
public class JwtInterceptor implements HandlerInterceptor {

    @Autowired
    private JwtUtil jwtUtil;
    
    @Autowired
    private JwtConfig jwtConfig;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String requestURI = request.getRequestURI();
        log.info("JWT拦截器处理请求: {} {}", request.getMethod(), requestURI);
        
        // 如果是OPTIONS请求，直接放行（CORS预检请求）
        if ("OPTIONS".equals(request.getMethod())) {
            log.info("OPTIONS请求，直接放行");
            return true;
        }
        
        // 检查是否为不需要token验证的路径
        if (isExcludedPath(requestURI, request)) {
            log.info("排除路径，不需要token验证: {}", requestURI);
            return true;
        }
        
        // 获取Authorization头
        String authorization = request.getHeader("Authorization");
        log.info("Authorization头: {}", authorization);
        
        if (authorization == null || !authorization.startsWith("Bearer ")) {
            log.warn("缺少或格式错误的Authorization头");
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write("{\"code\":500,\"message\":\"缺少或格式错误的Authorization头\",\"data\":null}");
            return false;
        }
        
        String token = authorization.substring(7);
        
        try {
            // 验证token是否过期
            if (jwtUtil.isTokenExpired(token)) {
                log.warn("token已过期");
                response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                response.setContentType("application/json;charset=UTF-8");
                response.getWriter().write("{\"code\":500,\"message\":\"token已过期，请重新登录\",\"data\":null}");
                return false;
            }
            
            // 检查token是否即将过期
            Date expiration = jwtUtil.getExpirationDateFromToken(token);
            long timeUntilExpiry = expiration.getTime() - System.currentTimeMillis();
            
            if (timeUntilExpiry <= jwtConfig.getExpirationWarningTime()) {
                // 在响应头中添加token即将过期的提示
                response.setHeader("X-Token-Expiring-Soon", "true");
                response.setHeader("X-Token-Expires-At", String.valueOf(expiration.getTime()));
                log.info("token即将过期，剩余时间: {} 分钟", timeUntilExpiry / (60 * 1000));
            }
            
            String username = jwtUtil.getUsernameFromToken(token);
            String type = jwtUtil.getTypeFromToken(token);
            
            if ("admin".equals(type)) {
                Long adminId = jwtUtil.getAdminIdFromToken(token);
                request.setAttribute("username", username);
                request.setAttribute("adminId", adminId);
                request.setAttribute("userId", adminId); // 为了兼容性，也设置userId
                log.info("管理员Token验证成功，设置adminId: {}, username: {}", adminId, username);
                
                if (adminId == null) {
                    log.warn("从管理员token中提取的adminId为null，token内容可能有问题");
                }
            } else {
                Long userId = jwtUtil.getUserIdFromToken(token);
                request.setAttribute("username", username);
                request.setAttribute("userId", userId);
                log.info("用户Token验证成功，设置userId: {}, username: {}", userId, username);
                
                if (userId == null) {
                    log.warn("从用户token中提取的userId为null，token内容可能有问题");
                }
            }
            return true;
        } catch (Exception e) {
            log.error("token验证失败: {}", e.getMessage());
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write("{\"code\":500,\"message\":\"token验证失败\",\"data\":null}");
            return false;
        }
    }
    
    /**
     * 判断是否为不需要token验证的路径
     */
    private boolean isExcludedPath(String requestURI, HttpServletRequest request) {
        String[] excludedPaths = {
            "/user/login",
            "/user/register", 
            "/user/sendEmailCode",
            "/user/resetPassword",
            "/user/forgotPassword",
            "/user/verifySecurityQuestions",
            "/user/getUserInfoForReset",
            "/user/validateEmail",
            "/user/validateUsername",
            "/user/validatePhone",
            "/user/validateEmailCode",
            "/user/verifyEmailCode",
            "/user/validateCaptcha",
            "/user/getCaptcha",
            "/user/refreshToken",
            "/doctor/login",
            "/doctor/register",
            "/doctor/hospitals",
            "/doctor/sendEmailCode",
            "/doctor/resetPassword",
            "/doctor/verifyEmailCode",
            "/admin/login",
            "/email/send-register-code",
            "/email/send-reset-code"
        };
        
        for (String path : excludedPaths) {
            if (requestURI.equals(path)) {
                return true;
            }
        }
        
        // 活动相关的公开接口（不需要登录）
        String[] publicActivityPaths = {
            "/activity/list",
            "/activity/listWithAdmin",
            "/activity/admin/names"
        };
        
        for (String path : publicActivityPaths) {
            if (requestURI.equals(path)) {
                return true;
            }
        }
        
        // 根据管理员姓名查询活动的接口（不需要登录）
        if (requestURI.matches("/activity/admin/.*/activities") && request.getMethod().equals("GET")) {
            return true;
        }
        
        // 活动详情查询（不需要登录）
        if (requestURI.matches("/activity/\\d+") && request.getMethod().equals("GET")) {
            return true;
        }
        
        // 活动封面访问（不需要登录）
        if (requestURI.startsWith("/activity/cover/")) {
            return true;
        }
        
        // 活动封面刷新（不需要登录）
        if (requestURI.matches("/activity/\\d+/refreshCover") && request.getMethod().equals("POST")) {
            return true;
        }
        
        // 检查报名状态（不需要登录）
        if (requestURI.equals("/activity-registration/check") && request.getMethod().equals("GET")) {
            return true;
        }
        
        return false;
    }
} 